﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Xenta.Attributes;
using Xenta.Utils;
using Xenta.Web.Controllers;

namespace Xenta.Web.Areas.Wizard.Controllers
{
    [Authenticate]
    public sealed class OrderController : ExtController
    {
        #region GET/POST Actions

        [HttpGet]
        public ActionResult Index(string flagMask)
        {
            var m = Svc.ProcessOperation("SearchOrders", new
            {
                CustomerID = JDM.Int32(Svc.Customer.EntityID),
                FlagMask = String.IsNullOrWhiteSpace(flagMask)
                    ? "Pending,Confirmed,Processing"
                    : flagMask,
                SortBy = new[] 
                {
                    "CreatedOn"
                },
                SortDir = "Descending"
            }, new
            {
                DisclosureLevel = "Base"
            });
            return View(m);
        }

        [HttpGet, RestoreState]
        public ActionResult Show(int id)
        {
            dynamic m = Svc.ProcessOperation("GetOrder", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Entire"
            });
            if(m == null)
                return HttpNotFound();
            if(JDM.Int32(m.Customer.EntityID) != JDM.Int32(Svc.Customer.EntityID))
                return new HttpUnauthorizedResult();
            return View(m);
        }

        [HttpPost, PersistState]
        public ActionResult Place(int cartID,
            int sellerID,
            int billingAddressID,
            int shippingAddressID,
            int sellerAddressID,
            Guid shippingMethodID,
            Guid salesModelID,
            IDictionary<String, String> attributes,
            IDictionary<String, String> soAttributes,
            IDictionary<String, String> smAttributes,
            string comment)
        {
            try
            {
                attributes = attributes ?? new Dictionary<String, String>();
                if(soAttributes != null)
                    attributes.AddValues(soAttributes);
                if(smAttributes != null)
                    attributes.AddValues(smAttributes);
                var m = Svc.ProcessOperation("PlaceOrder", new
                {
                    SellerID = sellerID,
                    CartID = cartID,
                    BillingAddressID = billingAddressID,
                    ShippingAddressID = shippingAddressID,
                    SellerAddressID = sellerAddressID,
                    ShippingMethodID = shippingMethodID,
                    SalesModelID = salesModelID,
                    Attributes = attributes
                });
                if(!String.IsNullOrWhiteSpace(comment))
                {
                    Svc.ProcessOperation("CreateOrderComment", new
                    {
                        OrderID = JDM.Int32(m.EntityID),
                        Text = comment,
                        Flags = "Active,Public",
                        SuppressNotification = true
                    });
                }
                Svc.ProcessOperation("ClearShoppingCart", new
                {
                    EntityID = cartID
                });
                return RedirectToAction(Loc.Act("Show").Set(new
                {
                    id = JDM.Int32(m.EntityID)
                }).Localized());
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Checkout").Ctrl("ShoppingCart").Set(new
            {
                id = cartID,
                billingAddressID,
                shippingAddressID,
                sellerAddressID
            }).Localized());
        }

        [HttpGet, PersistState]
        public ActionResult Confirm(int id)
        {
            try
            {
                Svc.ProcessOperation("ConfirmOrder", new
                {
                    EntityID = id
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Show").Set(new
            {
                id
            }).Localized());
        }

        [HttpGet, PersistState]
        public ActionResult Cancel(int id)
        {
            try
            {
                Svc.ProcessOperation("CancelOrder", new
                {
                    EntityID = id
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Show").Set(new
            {
                id
            }).Localized());
        }

        [HttpGet, PersistState]
        public ActionResult Issue(int id)
        {
            try
            {
                Svc.ProcessOperation("IssueOrder", new
                {
                    EntityID = id
                });
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Show").Set(new
            {
                id
            }).Localized());
        }

        [HttpGet, PersistState]
        public ActionResult PdfReport(int id)
        {
            dynamic m = Svc.ProcessOperation("GetOrder", new
            {
                EntityID = id
            }, new
            {
                DisclosureLevel = "Base"
            });
            if(m == null)
                return HttpNotFound();
            if(JDM.Int32(m.Customer.EntityID) != JDM.Int32(Svc.Customer.EntityID))
                return new HttpUnauthorizedResult();
            try
            {
                long rptElapsedTime = 0;
                string rptMimeType = String.Empty;
                var rptData = Svc.BuildReport("OrderPdfReport",
                    new Dictionary<String, String>
                    {
                        {"orderID", JDM.String(m.EntityID)},
                        {"locale", JDM.String(Svc.Localization.Code)}
                    },
                    out rptMimeType,
                    out rptElapsedTime);
                string dwlExt = MimeTypeHelper.TypeToExt(rptMimeType);
                string dwlName = String.Format("order_{0}_{1}.{2}", JDM.String(m.EntityID), JDM.String(m.Guid), dwlExt);
                return File(rptData, rptMimeType, dwlName);
            }
            catch(Exception ex)
            {
                ModelState.AddModelError("API", ex);
            }
            return RedirectToAction(Loc.Act("Show").Set(new
            {
                id
            }).Localized());
        }

        #endregion

        #region Child Actions

        [ChildActionOnly]
        public ActionResult _Comments(int id)
        {
            dynamic m = new ExpandoObject();

            m.EntityID = id;
            m.Comments = Svc.ProcessOperation("SearchOrderComments", new
            {
                HolderID = id,
                FlagMask = "Active,Public"
            }, new
            {
                DisclosureLevel = "Extended"
            }).Items;
            return PartialView(m);
        }

        #endregion
    }
}
